﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace WindowsGame1
{
    class Player
    {
        /// <summary>
        /// Player position
        /// </summary>
        protected Vector2 _position;
        /// <summary>
        /// direction of player
        /// </summary>
        protected Vector2 _direction;
        /// <summary>
        /// Graphics of Player Token
        /// </summary>
        protected Texture2D _playerToken;

        /// <summary>
        /// current GamePadState
        /// </summary>
        protected GamePadState _currentGamePadState;

        /// <summary>
        /// previous GamePadState
        /// </summary>
        protected GamePadState _lastGamePadState;


        /// <summary>
        /// current GamePadState
        /// </summary>
        protected KeyboardState _currentKeyBoardState;

        /// <summary>
        /// previous GamePadState
        /// </summary>
        protected KeyboardState _lastKeyBoardState;

        protected float _vibration;

        /// <summary>
        /// Constructor of Player
        /// </summary>
        /// <param name="token">the graphic to draw for the player</param>
        public Player(Texture2D token)
        {
            _playerToken = token;
            _position = new Vector2(0.0f, 0.0f);
            _vibration = 0.0f;
            //TODO: change for multiplayer
            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {
                _lastGamePadState = GamePad.GetState(PlayerIndex.One);
                _currentGamePadState = _lastGamePadState;
            }
            else
            {
                _lastKeyBoardState = Keyboard.GetState();
                _currentKeyBoardState = _lastKeyBoardState;
            }
 
        }

        /// <summary>
        /// Constructor of Player, if you already have a position
        /// </summary>
        /// <param name="token">graphic for the player</param>
        public Player(Texture2D token, Vector2 pos)
        {
            _playerToken = token;
            _position = pos;
            //TODO: change for multiplayer
            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {
                 // GamePadDeadZone.Circular
                _lastGamePadState = GamePad.GetState(PlayerIndex.One, GamePadDeadZone.Circular);
                _currentGamePadState = _lastGamePadState;
            }
            else
            {
                _lastKeyBoardState = Keyboard.GetState();
                _currentKeyBoardState = _lastKeyBoardState;
            }


        }

        ///// <summary>
        ///// player feedback: vibrate
        ///// </summary>
        ///// <param name="strength"></param>
        //public void vibrate(float strength)
        //{

        //}

        /// <summary>
        /// Update player movement
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="pressure"></param>
        public void update(Vector2 direction, float pressure)
        {
           
            Vector2 temp = Vector2.Zero;
            _vibration = 0.0f;

            if (GamePad.GetState(PlayerIndex.One).IsConnected) //if Gamepad is there, else use KeyBoard
            {
               //TODO: check if pad is connected!!!
               _lastGamePadState = _currentGamePadState;
               //TODO: change for Multiplayer!
               _currentGamePadState = GamePad.GetState(PlayerIndex.One, GamePadDeadZone.Circular);
            }
            else
            {
                _lastKeyBoardState = _currentKeyBoardState;
                _currentKeyBoardState = Keyboard.GetState();
            }


           
            //move the Player according to pressure and controls
            if (GamePad.GetState(PlayerIndex.One).IsConnected) //if Gamepad is there, else use KeyBoard
            {
                _direction = new Vector2(_currentGamePadState.ThumbSticks.Left.X, -_currentGamePadState.ThumbSticks.Left.Y);
            }
            else
            {
                if (_currentKeyBoardState.IsKeyDown(Keys.Up))
                    _direction.Y = -1.0f;
                else if (_currentKeyBoardState.IsKeyDown(Keys.Down))
                    _direction.Y = 1.0f;
                else
                    _direction.Y = 0.0f;

                if (_currentKeyBoardState.IsKeyDown(Keys.Left))
                    _direction.X = -1.0f;
                else if (_currentKeyBoardState.IsKeyDown(Keys.Right))
                    _direction.X = 1.0f;
                else
                    _direction.X = 0.0f;
            }
            
            // do extra checking because normalizing ZERO-vector is not defined!
            if(_direction.Length() > 1.0f)
                _direction.Normalize();
            if(direction.Length() > 1.0f)
                direction.Normalize();

            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {
                //strength of movement
                temp = (direction * pressure) - (_direction  * 1000);
                _direction = (direction * pressure) + (_direction  * 1000);
            }
            else
            {
                temp = (direction * pressure) - (_direction * 1000);
                _direction = (direction * pressure) + (_direction * 1000);
                
            }


            if (_direction.Length() > 1.0f)
                _direction.Normalize();
            _position += _direction;

            //vibration
            _vibration = temp.Length();

            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {

                if (_vibration > 1600) // it's over 1000!!!
                {
                    GamePad.SetVibration(PlayerIndex.One, MathHelper.Clamp((_vibration / 3000), 0.0f, 1.0f), MathHelper.Clamp((_vibration / 3000), 0.0f, 1.0f));
                }
                else if (_vibration > 100)
                {
                    GamePad.SetVibration(PlayerIndex.One, (_vibration / 3000), 0.0f);
                }
                else
                {
                    GamePad.SetVibration(PlayerIndex.One, 0.0f, 0.0f);
                }

            }
            

        }
        /// <summary>
        /// draw player
        /// </summary>
        public void draw(SpriteBatch gameSpriteBatch)
        {

            gameSpriteBatch.Draw(
                                    _playerToken, 
                                    new Rectangle((int)_position.X, (int)_position.Y, (int)_playerToken.Width / 4, (int)_playerToken.Height / 4), 
                                    null, 
                                    Color.White, 
                                    (float)Math.Atan2(_direction.Y, _direction.X) + MathHelper.PiOver2, 
                                    new Vector2(_playerToken.Width/8, _playerToken.Height/8), 
                                    SpriteEffects.None, 0);
        }


        #region properties

        public Vector2 position
        {
            get
            {
                return _position;
            }
            set
            {
                _position = value;
            }
        }

        public float vibration
        {
            get
            {
                return _vibration;
            }
        }
        #endregion


        public GamePadState currentState
        {
            get
            {
                return _currentGamePadState;
            }
        }

        public GamePadState lastState
        {
            get
            {
                return _lastGamePadState;
            }
        }
    }
}
